package com.supermap.dataservice.mysql.config;


import com.alibaba.druid.pool.DruidDataSource;
import com.supermap.dataservice.mysql.config.druid.DruidConfiguration;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author
 * @ClassName: MysqlDataSourceConfig
 * @Description: 手动创建数据源
 * 数据源配置类，在该类中生成多个数据源实例并将其注入到 ApplicationContext 中
 * @date 2017年12月27日 上午9:20:57
 */
@Configuration
public class DataSourceConfig {

    @Autowired
    private DruidConfiguration druidConfiguration;
    /**
     * application.properteis中对应属性的前缀。
     *
     * @return
     */
    @Bean(name = "ds1")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.db1")
    public DataSource dataSource1() {
        DruidDataSource druiddatasource = new DruidDataSource();
        return druidConfiguration.dataSource(druiddatasource);
    }

    /**
     * application.properteis中对应属性的前缀。
     *
     * @return
     */
    @Bean(name = "ds2")
    @ConfigurationProperties(prefix = "spring.datasource.db2")
    public DataSource dataSource2() {
        DruidDataSource druiddatasource = new DruidDataSource();
        return druidConfiguration.dataSource(druiddatasource);
    }

    /**
     * application.properteis中对应属性的前缀。
     *
     * @return
     */
    @Bean(name = "ds3")
    @ConfigurationProperties(prefix = "spring.datasource.db3")
    public DataSource dataSource3() {
        DruidDataSource druiddatasource = new DruidDataSource();
        return druidConfiguration.dataSource(druiddatasource);
    }
    @Bean(name = "ds4")
    @ConfigurationProperties(prefix = "spring.datasource.db4")
    public DataSource dataSource4() {
        DruidDataSource druiddatasource = new DruidDataSource();
        return druidConfiguration.dataSource(druiddatasource);
    }

    //将要执行的sql进行日志打印(不想拦截，就把这方法注释掉)
    @Bean("sqlPrintInterceptor")
    public SqlPrintInterceptor sqlPrintInterceptor(){
        return new SqlPrintInterceptor();
    }

    /**
     * @return DataSource    返回类型
     * @Title: dynamicDataSource
     * @Description: 动态数据源: 通过AOP在不同数据源之间动态切换
     */
    @Bean("dynamicDataSource")
    public DataSource dynamicDataSource() {
        DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();
        Map<Object, Object> dataSourceMap = new HashMap<Object, Object>(2);
        dataSourceMap.put("ds1", dataSource1());
        dataSourceMap.put("ds2", dataSource2());
        dataSourceMap.put("ds3", dataSource3());
        dataSourceMap.put("ds4", dataSource4());

        // 将主数据源设置为默认值
        dynamicRoutingDataSource.setDefaultTargetDataSource(dataSource2());
        // 将主数据源和从数据源设置为目标数据源
        dynamicRoutingDataSource.setTargetDataSources(dataSourceMap);
        //将数据源键放入DataSourceContextHolder中，以判断数据源是否存在
        DynamicDataSourceContextHolder.dataSourceKeys.addAll(dataSourceMap.keySet());

        return dynamicRoutingDataSource;
    }

    /**
     * @param @return 设定文件
     * @return SqlSessionFactoryBean    返回类型
     * @Title: sqlSessionFactoryBean
     * @Description: SqlSessionFactory配置数据源
     */
    @Bean
    @ConfigurationProperties(prefix = "mybatis")
    public SqlSessionFactoryBean sqlSessionFactoryBean() {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 将所有数据源放入sqlessionfactorybean
        sqlSessionFactoryBean.setDataSource(dynamicDataSource());
        //添加分页插件、打印sql插件
        Interceptor[] plugins = new Interceptor[]{sqlPrintInterceptor()};
        sqlSessionFactoryBean.setPlugins(plugins);
        /**
         * 阿卡重写
         * */
        org.apache.ibatis.session.Configuration configuration=new org.apache.ibatis.session.Configuration();
        configuration.setCallSettersOnNulls(true);
        sqlSessionFactoryBean.setConfiguration(configuration);
        return sqlSessionFactoryBean;
    }

    /**
     * @return PlatformTransactionManager    返回类型
     * @Title: transactionManager
     * @Description: 事物管理
     */
    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dynamicDataSource());
    }

}
